home *** CD-ROM | disk | FTP | other *** search
-
- Nintendo Entertainment System Architecture
- version 1.4 [09/09/1996]
-
- by Marat Fayzullin [fms@freeflight.com]
- WWW: http://www.freeflight.com/fms/
- IRC: RST38h
-
-
- The following document describes the workings of Nintendo Entertainment
- System videogame console, also known as Famicom in the East (Korea, Japan),
- and Dandy in Europe (Russia, etc.). Note that this document is in no way
- based on any official Nintendo information and may be incomplete and
- incorrect in many places. "Nintendo Entertainment System" and "Famicom" are
- registered trademarks of Nintendo.
-
- I would like to thank following people for their help in obtaining this
- information and writing a NES emulator, as well as the moral support from
- some of them:
-
- (sorted alphabetically)
- Pascal Felber Pan of Anthrox John Stiles
- Kawasedo Patrick Lesaard Tink
- Marcel de Kogel Paul Robson Bas Vijfwinkel
- Alex Krasivsky Serge Skorobogatov
-
- The current version of this file is missing some information, such as
- sound hardware. I will add these parts in later releases. If you have any
- information on NES, which is not in this manual, feel free to write to
- fms@freeflight.com. Your help will be appreciated.
-
-
- ******************************* Contents *******************************
-
- 1. General Architecture
- 2. Interrupts
- 3. I/O Ports
- 4. PPU Memory
- 5. Hit/VBlank Bits
- 6. Joysticks
- 7. Sprites
- 8. Memory Mappers
- a) Sequential
- b) Konami
- c) VROM Switch
- d) 5202 Chip
- e) Others
- 9. Sound (to be written)
-
-
- ************************* General Architecture *************************
-
- NES is based on the 6502 CPU, and a custom video controller known as PPU
- (Picture Processing Unit). The PPU's video memory is separated from the
- main CPU memory and can be read/written via special ports. Cartridges may
- contain both ROM appearing in the main CPU address space at $8000-$FFFF,
- and VROM or VRAM appearing in the PPU address space at $0000-$1FFF and
- containing the Pattern Tables (aka Tile Tables). In smaller cartridges,
- which only have 16kB ROM, it takes place at $C000-$FFFF leaving $8000-$BFFF
- area unused. Internal NES VRAM is located at addresses $2000-$3FFF in the
- PPU memory. Some cartridges also have RAM at $6000-$7FFF, which may or may
- not be battery-backed.
-
- CPU Memory Map
- --------------------------------------- $10000
- Upper Bank of Cartridge ROM
- --------------------------------------- $C000
- Lower Bank of Cartridge ROM
- --------------------------------------- $8000
- Cartridge RAM (may be battery-backed)
- --------------------------------------- $6000
- Expansion Modules
- --------------------------------------- $5000
- Input/Output
- --------------------------------------- $2000
- 2kB Internal RAM, mirrored 4 times
- --------------------------------------- $0000
-
-
- ****************************** Interrupts ******************************
-
- NES uses non-maskable interrupts (NMIs) generated by PPU in the end of
- each frame (so-called VBlank interrupts). Maskable interrupts, or IRQs,
- can also be generated by circuitry in a cart, but most carts do not
- generate them. The VBlank interrupts can be enabled/disabled by writing
- 1/0 into 7th bit of $2000. When a VBlank interrupts occur, CPU pushes
- return address and the status register on stack, and jumps to the address
- stored at location $FFFA (ROM in NES). The interrupt handler is supposed
- to finish its execution with RTI command which returns CPU to the main
- program execution. More information on the interrupt handling can be found
- in a decent book on 6502 CPU.
-
-
- ****************************** I/O ports *******************************
-
- NES internal I/O ports are mapped into the areas of $2000-$2007 and
- $4000-$4017. Some ports' usage is unknown or unclear, and any information
- is appreciated.
-
- I/O Ports Map
- ------+-----+---------------------------------------------------------------
- $2000 | RW | PPU Control Register 1
- | 0-1 | Name Table to show:
- | |
- | | +-----------+-----------+
- | | | 2 ($2800) | 3 ($2C00) |
- | | +-----------+-----------+
- | | | 0 ($2000) | 1 ($2400) |
- | | +-----------+-----------+
- | |
- | | Remember, though, that because of the mirroring, there are
- | | only 2 real Name Tables, not 4.
- | 2 | Vertical Write, 1 = PPU memory address increments by 32:
- | |
- | | Name Table, VW=0 Name Table, VW=1
- | | +----------------+ +----------------+
- | | |----> write | | | write |
- | | | | | V |
- | |
- | 3 | Sprite Pattern Table address, 1 = $1000, 0 = $0000
- | 4 | Screen Pattern Table address, 1 = $1000, 0 = $0000
- | 5 | Sprite Size, 1 = 8x16, 0 = 8x8
- | 6 | Hit Switch, 1 = generate interrupts on Hit (incorrect ???)
- | 7 | VBlank Switch, 1 = generate interrupts on VBlank
- ------+-----+---------------------------------------------------------------
- $2001 | RW | PPU Control Register 2
- | 0 | Unknown (???)
- | 1 | Image Mask, 0 = don't show left 8 columns of the screen
- | 2 | Sprite Mask, 0 = don't show sprites in left 8 columns
- | 3 | Screen Switch, 1 = show picture, 0 = blank screen
- | 4 | Sprites Switch, 1 = show sprites, 0 = hide sprites
- | 5-7 | Unknown (???)
- ------+-----+---------------------------------------------------------------
- $2002 | R | PPU Status Register
- | 0-5 | Unknown (???)
- | 6 | Hit Flag, 1 = PPU refresh has hit sprite #0
- | | This flag resets to 0 when VBlank starts, or CPU reads $2002
- | | (see "Hit/VBlank Bits").
- | 7 | VBlank Flag, 1 = PPU is generating a Vertical Blanking Impulse
- | | This flag resets to 0 when VBlank ends, or CPU reads $2002
- | | (see "Hit/VBlank Bits").
- ------+-----+---------------------------------------------------------------
- $2003 | W | Sprite Memory Address
- | | Used to set the address in the 256-byte Sprite Memory to be
- | | accessed via $2004. This address will increment by 1 after
- | | each access to $2004. The Sprite Memory contains coordinates,
- | | colors, and other attributes of the sprites (see "Sprites").
- ------+-----+---------------------------------------------------------------
- $2004 | RW | Sprite Memory Data
- | | Used to read/write the Sprite Memory. The address is set via
- | | $2003 and increments after each access. The Sprite Memory
- | | contains coordinates, colors, and other attributes of the
- | | sprites (see "Sprites").
- ------+-----+---------------------------------------------------------------
- $2005 | W | Background Scroll
- | | There are two scroll registers, vertical and horizontal,
- | | which are both written via this port. The first value written
- | | will go into the Vertical Scroll Register (unless it is >239,
- | | then it will be ignored). The second value will appear in the
- | | Horizontal Scroll Register. The Name Tables are assumed to be
- | | arranged in the following way:
- | |
- | | +-----------+-----------+
- | | | 2 ($2800) | 3 ($2C00) |
- | | +-----------+-----------+
- | | | 0 ($2000) | 1 ($2400) |
- | | +-----------+-----------+
- | |
- | | When scrolled, the picture may span over several Name Tables.
- | | Remember, though, that because of the mirroring, there are
- | | only 2 real Name Tables, not 4.
- ------+-----+---------------------------------------------------------------
- $2006 | | PPU Memory Address
- | | See "PPU Memory".
- ------+-----+---------------------------------------------------------------
- $2007 | | PPU Memory Data
- | | See "PPU Memory".
- ------+-----+---------------------------------------------------------------
- $4000-$4013 | Sound Registers
- | See "Sound".
- ------+-----+---------------------------------------------------------------
- $4014 | W | DMA Access to the Sprite Memory
- | | Writing a value N into this port, causes an area of CPU memory
- | | at address $100*N to be transferred into the Sprite Memory.
- ------+-----+---------------------------------------------------------------
- $4015 | W | Sound Switch
- | 0 | Channel 1, 1 = enable sound
- | 1 | Channel 2, 1 = enable sound
- | 2 | Channel 3, 1 = enable sound
- | 3 | Channel 4, 1 = enable sound
- | 4 | Channel 5, 1 = enable sound
- | 5-7 | Unused (???)
- ------+-----+---------------------------------------------------------------
- $4016 | RW | Joystick 1 + Strobe
- | 0 | Joystick 1 data
- | 1 | Joystick 1 presence, 0 = connected
- | 2-5 | Unused, set to 0 (???)
- | 6-7 | Unknown, set to 10 (???)
- | | See "Joysticks".
- ------+-----+---------------------------------------------------------------
- $4017 | R | Joystick 2
- | 0 | Joystick 2 data
- | 1 | Joystick 2 presence, 0 = connected
- | 2-5 | Unused, set to 0 (???)
- | 6-7 | Unknown, set to 10 (???)
- | | See "Joysticks".
- ------+-----+---------------------------------------------------------------
-
-
- ****************************** PPU Memory ******************************
-
- In a real NES, reading/writing PPU memory should only be attempted
- during VBlank period. Many smaller ROMs have read-only memory (VROM) for
- the Pattern Tables. In this case, you won't be able to write into this
- memory. The $3F00 and $3F10 locations in VRAM mirror each other (i.e. it
- is the same memory cell) and define the background color of the picture.
-
- Writing to PPU memory:
- a) Write upper address byte into $2006
- b) Write lower address byte into $2006
- c) Write data into $2007. After each write, the address will
- increment either by 1 (bit 2 of $2000 is 0) or by 32 (bit 2 of
- $2000 is 1).
-
- Reading from PPU memory:
- a) Write upper address byte into $2006
- b) Write lower address byte into $2006
- c) Read data from $2007. The first byte read from $2007 will be
- invalid. Then, the address will increment by 1 after each
- read.
-
- Name Table contains tile numbers organized into 32 rows of 32 bytes
- each. Tiles are 8x8 pixels each. Therefore, the whole Name Table is 32x32
- tiles or 256x256 pixels. In the NTSC version of NES, upper and lower 16
- pixels are not shown, thus, the screen becomes 256x224 pixels. In the PAL
- version of NES, upper and lower 8 pixels are not show, thus, the screen
- becomes 256x240 pixels.
-
- Pattern Table contains tile images in the following format:
-
- Character Colors Contents of Pattern Table
- ...o.... 00010000 00010000 $10 +-> 00000000 $00
- ..O.O... 00202000 00000000 $00 | 00101000 $28
- .0...0.. 03000300 01000100 $44 | 01000100 $44
- O.....O. 20000020 00000000 $00 | 10000010 $82
- ooooooo. -> 11111110 11111110 $FE | 00000000 $00
- O.....O. 20000020 00000000 $00 | 10000010 $82
- 0.....0. 30000030 10000010 $82 | 10000010 $82
- ........ 00000000 00000000 $00 | 00000000 $00
- +---------+
-
- Note that only two bits for each pixel of a character are stored in the
- Pattern Table. Other two are taken from the Attribute Table. Thus, the total
- number of simultaneous colors on the NES screen is 16.
-
- Each byte in the Attribute Table represents a 4x4 group of tiles on the
- screen, which makes an 8x8 attribute table. Each 4x4 tile group is
- subdivided into four 2x2 squares as follows:
-
- (0,0) (1,0) 0| (2,0) (3,0) 1
- (0,1) (1,1) | (2,1) (3,1)
- --------------+----------------
- (0,2) (1,2) 2| (2,2) (3,2) 3
- (0,3) (1,3) | (2,3) (3,3)
-
- The attribute byte contains upper two bits of the color number for each
- 2x2 square (the lower two bits are stored in the Pattern Table):
-
- Bits Function Tiles
- --------------------------------------------------------------
- 7,6 Upper color bits for square 3 (2,2),(3,2),(2,3),(3,3)
- 5,4 Upper color bits for square 2 (0,2),(1,2),(0,3),(1,3)
- 3,2 Upper color bits for square 1 (2,0),(3,0),(2,1),(3,1)
- 1,0 Upper color bits for square 0 (0,0),(1,0),(0,1),(1,1)
-
- There are two 16-byte Palette Tables: the one at $3F00, used for the
- picture, and another one at $3F10, containing the sprite palette. The
- $3F00 and $3F10 locations in VRAM mirror each other (i.e. it is the same
- memory cell) and define the background color of the picture.
-
- There is only enough VRAM for 2 Name Tables and Attribute Tables. Two
- others are going to be mirrors of the first two, i.e. exact copies of them.
- Which pages are mirrored depends on the cartridge circuitry. With vertical
- mirroring, tables 2 and 3 are the mirrors of pages 0 and 1 appropriately.
- With horizontal mirroring, pages 1 and 3 are the mirrors of pages 0 and 2
- appropriately.
-
- PPU Memory Map
- --------------------------------------- $4000
- Empty
- --------------------------------------- $3F20
- Sprite Palette
- --------------------------------------- $3F10
- Image Palette
- --------------------------------------- $3F00
- Empty
- --------------------------------------- $3000
- Attribute Table 3
- --------------------------------------- $2FC0
- Name Table 3 (32x25 tiles)
- --------------------------------------- $2C00
- Attribute Table 2
- --------------------------------------- $2BC0
- Name Table 2 (32x25 tiles)
- --------------------------------------- $2800
- Attribute Table 1
- --------------------------------------- $27C0
- Name Table 1 (32x25 tiles)
- --------------------------------------- $2400
- Attribute Table 0
- --------------------------------------- $23C0
- Name Table 0 (32x25 tiles)
- --------------------------------------- $2000
- Pattern Table 1 (256x2x8, may be VROM)
- --------------------------------------- $1000
- Pattern Table 0 (256x2x8, may be VROM)
- --------------------------------------- $0000
-
-
- *************************** Hit/VBlank Bits ****************************
-
- The VBlank flag is contained in the 7th bit of read-only location $2002.
- It indicates whether PPU is scanning the screen, or generating a vertical
- blanking impulse. It is set in the end of each frame (scanline 232), and
- stays on until the next screen refresh starts from the scanline 8. The
- program can reset this bit prematurely by reading from $2002.
-
- The Hit flag is contained in the 6th bit of read-only location $2002.
- It goes to 1 when PPU starts refreshing the first scanline where sprite#0
- is located. For example, if sprite#0's Y coordinate is 34, the Hit flag
- will be set in scanline 34. The Hit flag is reset when vertical blanking
- impulse starts. The program can reset this bit prematurely by reading from
- $2002.
-
-
- ******************************* Joysticks ******************************
-
- There are two joysticks which are accessed via locations $4016 and
- $4017. To reset joysticks, write first 1, then 0 into $4016. This way, you
- will generate a strobe in the joysticks' circuitry. Then, read either from
- $4016 (for joystick 0) or from $4017 (for joystick 1). Each read will
- give you the status of a single button in the 0th bit (1 if pressed, 0
- otherwise):
-
- Read # | 1 2 3 4 5 6 7 8
- -------+---------------------------------------------------------
- Button | A B SELECT START UP DOWN LEFT RIGHT
-
- Bit 1 indicates whether joystick is connected to the port or not. It is
- set to 0 if the joystick is connected, 1 otherwise. Bits 6 and 7 of
- $4016/$4017 also seem to have some significance, which is not clear yet.
- The rest of bits is set to zeroes. Some games expect to get *exactly* $41
- from $4016/$4017, if a button is pressed, which has to be taken into
- account.
-
-
- ******************************* Sprites ********************************
-
- There are 64 sprites, which can be either 8x8 or 8x16 pixels. Sprites
- patterns are stored in on of the Pattern Tables in the PPU Memory. Sprite
- attributes are stored in the Sprite Memory of 256 bytes, which is not a
- part of neither CPU nor PPU address space. The entire contents of Sprite
- Memory can be written via DMA transfer using location $4014 (see above).
- Sprite Memory can also be accessed byte-by-byte by putting the starting
- address into $2003 and then writing/reading $2004 (the address will be
- incremented after each access). The format of sprite attributes is as
- follows:
-
- Sprite Attribute RAM:
- | Sprite#0 | Sprite#1 | ... | Sprite#62 | Sprite#63 |
- | |
- +---- 4 bytes: 0: Y position of the left-top corner - 1
- 1: Sprite pattern number
- 2: Color and attributes:
- bits 1,0: two upper bits of color
- bits 2,3,4: Unknown (???)
- bit 5: if 1, display sprite behind background
- bit 6: if 1, flip sprite horizontally
- bit 7: if 1, flip sprite vertically
- 3: X position of the left-top corner
-
- Sprite patterns are fetched in the exactly same way as the tile patterns
- for the background picture. The only difference occurs in the 16x8
- sprites: the top half of the sprite is taken from the Sprite Pattern Table
- set in the $2000 port, while the bottom part is taken from the same
- location of the alternative Pattern Table. Therefore, if PPU is displaying
- a 16x8 sprite, and the Sprite Pattern Table is set to $1000, the bottom
- half of this sprite will be taken out of the $0000 Pattern Table, and vice
- versa.
-
-
- **************************** Memory Mappers ****************************
-
- There are many diffirent memory mappers (aka MMCs) used in the NES
- cartridges. They are used to switch ROM and VROM pages, and do some other
- tasks. I will only describe the MMCs I'm familiar with. Any new
- information on these and other MMCs is highly appreciated. The MMC
- numbers are given in terms of the .NES file field "Mapper Type".
-
-
- 1. Mapper #1, Sequential
-
- This is a sequential mapper used in many 256kB cartridges, such as
- Bomberman 2, Destiny Of The Emperor, Megaman 2, Airwolf, Operation Wolf,
- Castlevania 2, Silk Worm, Yoshi, Break Thru. It may be used to switch ROM
- and VROM. If there is no VROM, 8kB of VRAM is present at $0000. In some
- cases (mostly RPG games) such cartridges also contain battery-backed RAM
- at $6000-$7FFF. The mapper has four 5bit registers, which are accessed via
- following addresses:
-
- Register Address Range Function
- ---------------------------------------------------------------------------
- 0 $8000-$9FFF Mirroring and VROM Page Size select
- The 0th bit of this register selects the mirroring type (1 for
- horizontal, 0 for vertical). The 4th bit selects the size of
- VROM pages. When it is 1, two 4kB VROM pages can be switched
- independently at $0000 and $1000. Otherwise, there is a single
- 8kB VROM page at $0000.
-
- 1 $A000-$BFFF VROM page select
- This register sets either 8kB or 4kB VROM page at $0000,
- depending on the page size selected via register 0.
-
- 2 $C000-$DFFF Second VROM page select for 4kB pages
- If 4kB VROM pages selected via register 0, this register sets
- the VROM page at $1000. Otherwise, its value is ignored.
-
- 3 $E000-$FFFF ROM page select
- This register sets 16kB ROM page at $8000. The page at $C000 is
- always hardwired to the last ROM page in the cartridge. The
- cartridge starts with page 0 at $8000.
- ---------------------------------------------------------------------------
-
- In order to write to a mapper register, write $80 into any of the
- locations first. This will reset the mapper. Then write the value bit by
- bit into an appropriate address range. For example, the following assembly
- code will write $0C into register 3:
-
- lda #$80 ; Resetting mapper
- sta $8000 ;
- lda #$0C ; This is our value
- sta $EFD9 ; Writing bit 0
- lsr a ; Shifting
- sta $EFD9 ; Writing bit 1
- lsr a ; Shifting
- sta $EFD9 ; Writing bit 2
- lsr a ; Shifting
- sta $EFD9 ; Writing bit 3
- lsr a ; Shifting
- sta $EFD9 ; Writing bit 4
-
-
- 2. Mapper #2, Konami
-
- This is a quite simple mapper used in most Konami (Life Force,
- Castlevania, Metal Gear) and some other cartridges. It only switches the
- ROM. All cartridges with this mapper have 8kB VRAM at $0000 (i.e. no
- VROM). The mapper has a single 8bit register which can be written via
- locations $8000-$FFFF. It contains a number of 16kB ROM page at $8000.
- The page at $C000 is always hardwired to the last ROM page in the
- cartridge. The cartridge starts with page 0 at $8000.
-
- There is one more thing to note about this mapper: although any address
- in the $8000-$FFFF range can be used to access the mapper, most games
- prefer to use the address with the last digit equal to the value they
- write out. Thus, $07 can be written to $9FF7, $05 to $9FF5, and so forth.
- The reason for this is unknown.
-
-
- 3. Mapper #3, VROM Switch
-
- Mapper #3, also known as a VROM switch, is used in the Goonies series
- and many Japanese-only games. It only allows you to switch 8kB pages of
- VROM. The ROM is either 16kB or 32kB and is not paged. The mapper has a
- single 8bit register which can be written via locations $8000-$FFFF. It
- contains a number of 8kB VROM page at $0000.
-
- As with mapper #2, many games use locations with the last digit equal to
- the value being written. I do not know why.
-
-
- 4. Mapper #4, 5202 Chip (???)
-
- This mapper (or should I say 'an expansion chip'?) is used in many
- recent cartridges, such as Batman Returns, Super Contra, Vindicators,
- Silver Surfer, etc. It is an extremely complicated device, which is able
- to generate its own interrupts via IRQ line, and has a set of commands to
- switch ROM and VROM. VROM pages are 1kB, ROM pages appear to be 8kB. I do
- not completely understand how this mapper works, so any information is
- appreciated.
-
- The chip is controlled via following locations:
-
- Address Function
- ---------------------------------------------------------------------------
- $8000 A command number (0-7) is written here. Also, write to this
- register appears to reset the change made by a write into $E000.
- $8001 An value for command is written here.
- $A000 The 0th bit controls mirroring (1 = horizontal mirroring).
- $A001 Same as $8001 (???)
- $C000 Unknown
- $C001 Unknown
- $E000 The 5th bit appears to swap memory at $8000-$8FFF and
- $A000-$AFFF, when set to 1.
- $E001 Unknown
- ---------------------------------------------------------------------------
-
- In order to use the mapper, you should first write a command number
- into $8000, and then a value (page number) into $8001. Following commands
- exist:
-
- Cmd Function
- ---------------------------------------------------------------------------
- 0 Select 2 consequent 1kB VROM pages at $0000. The 0th bit of a value
- written into $8001 does not matter, i.e. 5 will always select pages
- 4 and 5.
- 1 Select 2 consequent 1kB VROM pages at $0800. The 0th bit of a value
- written into $8001 does not matter, i.e. 5 will always select pages
- 4 and 5.
- 2 Select a 1kB VROM page at $1000.
- 3 Select a 1kB VROM page at $1400.
- 4 Select a 1kB VROM page at $1800.
- 5 Select a 1kB VROM page at $1C00.
- 6 Select a 8kB ROM page at $8000. The initial value seems to be 0.
- 7 Select a 8kB ROM page at $A000. The initial value seems to be 1.
- ---------------------------------------------------------------------------
-
- Note that the ROM pages at $C000 and $E000 are hardwired to the last
- pages of the ROM, and can not be switched (they can be swapped via
- $E000 though).
-
-
- 5. Other mappers
-
- There are several other mappers, some of them very sophisticated. iNES
- partially supports them, but as this support either doesn't work
- correctly, or the mappers are uncommon (such as 100-in-1 cartridge mapper,
- I don't cover them here.
-
-
- ******************************** Sound *********************************
-
- To be written.
-
-
-
- ---------------------
- Marat Fayzullin
-